import React, { useEffect, useState, useCallback } from 'react';
import { useNavigate } from 'react-router-dom';
import {
  Box,
  Button,
  Dialog,
  DialogActions,
  DialogContent,
  DialogTitle,
  TextField,
  Typography,
  IconButton,
  Snackbar,
  Alert,
  Tooltip,
  Card,
  CardContent,
  Grid,
  Chip,
  useTheme,
  useMediaQuery,
  Divider,
} from '@mui/material';
import {
  Add as AddIcon,
  Delete as DeleteIcon,
  Edit as EditIcon,
  Visibility as VisibilityIcon,
  Wifi as WifiIcon,
  WifiOff as WifiOffIcon,
} from '@mui/icons-material';
import apiClient from '../services/apiService';
import { websocketService } from '../services/websocketService';
import { Device } from '../types/device';

const DeviceList: React.FC = () => {
  const navigate = useNavigate();
  const theme = useTheme();
  const isMobile = useMediaQuery(theme.breakpoints.down('sm'));
  const [devices, setDevices] = useState<Device[]>([]);
  const [openDialog, setOpenDialog] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [newDevice, setNewDevice] = useState({
    deviceId: '',
    name: '',
    type: '',
    password: '',
  });

  const fetchDevices = useCallback(async () => {
    try {
      const response = await apiClient.get('/devices');
      setDevices(response.data);
      setError(null);
    } catch (error: any) {
      console.error('获取设备列表失败:', error);
      setError(error.response?.data?.message || '获取设备列表失败');
    }
  }, []);

  useEffect(() => {
    fetchDevices();

    // 处理设备状态变化
    const handleDeviceStatusChange = (data: any) => {
      setDevices(prevDevices => 
        prevDevices.map(device => 
          device.deviceId === data.deviceId
            ? {
                ...device,
                status: data.status,
                lastSeen: data.timestamp,
                lastHeartbeat: data.lastHeartbeat,
                temperature: data.temperature,
                humidity: data.humidity,
                updatedAt: new Date().toISOString()
              }
            : device
        )
      );
    };

    // 处理设备状态广播
    const handleDeviceStatusBroadcast = (data: any) => {
      setDevices(prevDevices => 
        prevDevices.map(device => {
          if (device.deviceId !== data.deviceId) {
            return device;
          }

          const updatedDevice = {
            ...device,
            status: data.status,
            lastSeen: data.metadata.lastSeen,
            updatedAt: new Date().toISOString()
          };

          // 只有在设备有配置且连接类型为 wifi 时才更新 wifi 配置
          if (device.config && data.metadata.connectionType === 'wifi') {
            updatedDevice.config = {
              ...device.config,
              wifi: {
                ...device.config.wifi,
                ssid: device.config.wifi?.ssid || '',
                password: device.config.wifi?.password || ''
              }
            };
          }

          return updatedDevice;
        })
      );
    };

    // 订阅 WebSocket 事件
    websocketService.subscribe('device_status_change', handleDeviceStatusChange);
    websocketService.subscribe('device_status_broadcast', handleDeviceStatusBroadcast);

    // 设置数据定时刷新
    const dataRefreshInterval = setInterval(() => {
      fetchDevices();
    }, 10000); // 每10秒刷新一次数据

    return () => {
      // 取消订阅
      websocketService.unsubscribe('device_status_change', handleDeviceStatusChange);
      websocketService.unsubscribe('device_status_broadcast', handleDeviceStatusBroadcast);
      clearInterval(dataRefreshInterval);
    };
  }, [fetchDevices]);

  const handleAddDevice = async () => {
    try {
      // 验证必填字段
      if (!newDevice.deviceId || !newDevice.name || !newDevice.type || !newDevice.password) {
        setError('请填写所有必填字段');
        return;
      }

      await apiClient.post('/devices', newDevice);
      setOpenDialog(false);
      setNewDevice({ deviceId: '', name: '', type: '', password: '' });
      fetchDevices();
    } catch (error: any) {
      setError(error.response?.data?.message || '添加设备失败');
    }
  };

  const handleDeleteDevice = async (deviceId: string) => {
    if (window.confirm('确定要删除这个设备吗？')) {
      try {
        await apiClient.delete(`/devices/${deviceId}`);
        fetchDevices();
      } catch (error: any) {
        setError(error.response?.data?.message || '删除设备失败');
      }
    }
  };

  // 优化设备列表渲染
  const renderDeviceCard = (device: Device) => (
    <Grid item xs={12} sm={6} md={4} key={device.deviceId}>
      <Card 
        sx={{ 
          height: '100%',
          display: 'flex',
          flexDirection: 'column',
          transition: 'transform 0.2s',
          '&:hover': {
            transform: 'translateY(-4px)'
          }
        }}
      >
        <CardContent>
          <Box sx={{ 
            display: 'flex', 
            justifyContent: 'space-between',
            alignItems: 'flex-start',
            mb: 2
          }}>
            <Box>
              <Typography variant="h6" gutterBottom>
                {device.name}
              </Typography>
              <Typography 
                variant="body2" 
                color="text.secondary"
                sx={{ mb: 1 }}
              >
                ID: {device.deviceId}
              </Typography>
              <Chip
                icon={device.status === 'online' ? <WifiIcon /> : <WifiOffIcon />}
                label={device.status === 'online' ? '在线' : '离线'}
                color={device.status === 'online' ? 'success' : 'error'}
                size="small"
              />
            </Box>
            <Box>
              <Tooltip title="查看详情">
                <IconButton
                  onClick={() => navigate(`/devices/${device.deviceId}`)}
                  size={isMobile ? "small" : "medium"}
                >
                  <VisibilityIcon />
                </IconButton>
              </Tooltip>
              <Tooltip title="编辑设备">
                <IconButton
                  onClick={() => navigate(`/devices/${device.deviceId}/edit`)}
                  size={isMobile ? "small" : "medium"}
                >
                  <EditIcon />
                </IconButton>
              </Tooltip>
              <Tooltip title="删除设备">
                <IconButton 
                  onClick={() => handleDeleteDevice(device.deviceId)}
                  size={isMobile ? "small" : "medium"}
                >
                  <DeleteIcon />
                </IconButton>
              </Tooltip>
            </Box>
          </Box>

          <Divider sx={{ my: 2 }} />

          <Grid container spacing={2}>
            <Grid item xs={6}>
              <Typography variant="body2" color="text.secondary">
                类型
              </Typography>
              <Typography variant="body1">
                {device.type}
              </Typography>
            </Grid>
            <Grid item xs={6}>
              <Typography variant="body2" color="text.secondary">
                最后心跳
              </Typography>
              <Typography variant="body1">
                {device.lastHeartbeat ? new Date(device.lastHeartbeat).toLocaleString() : '未知'}
              </Typography>
            </Grid>
            <Grid item xs={6}>
              <Typography variant="body2" color="text.secondary">
                温度
              </Typography>
              <Typography variant="body1">
                {device.temperature}°C
              </Typography>
            </Grid>
            <Grid item xs={6}>
              <Typography variant="body2" color="text.secondary">
                湿度
              </Typography>
              <Typography variant="body1">
                {device.humidity}%
              </Typography>
            </Grid>
          </Grid>
        </CardContent>
      </Card>
    </Grid>
  );

  return (
    <Box sx={{ p: { xs: 2, sm: 3 } }}>
      <Box sx={{ 
        display: 'flex', 
        justifyContent: 'space-between', 
        alignItems: 'center',
        mb: { xs: 2, sm: 3 },
        flexDirection: { xs: 'column', sm: 'row' },
        gap: { xs: 2, sm: 0 }
      }}>
        <Typography 
          variant={isMobile ? "h5" : "h4"}
          sx={{ fontWeight: 600 }}
        >
          设备管理
        </Typography>
        <Button
          variant="contained"
          startIcon={<AddIcon />}
          onClick={() => setOpenDialog(true)}
          fullWidth={isMobile}
        >
          添加设备
        </Button>
      </Box>

      <Grid container spacing={2}>
        {devices.map(renderDeviceCard)}
      </Grid>

      <Dialog 
        open={openDialog} 
        onClose={() => setOpenDialog(false)}
        fullWidth
        maxWidth="sm"
      >
        <DialogTitle>添加新设备</DialogTitle>
        <DialogContent>
          <TextField
            autoFocus
            margin="dense"
            label="设备ID"
            fullWidth
            value={newDevice.deviceId}
            onChange={(e) =>
              setNewDevice({ ...newDevice, deviceId: e.target.value })
            }
            size={isMobile ? "small" : "medium"}
          />
          <TextField
            margin="dense"
            label="设备名称"
            fullWidth
            value={newDevice.name}
            onChange={(e) =>
              setNewDevice({ ...newDevice, name: e.target.value })
            }
            size={isMobile ? "small" : "medium"}
          />
          <TextField
            margin="dense"
            label="设备类型"
            fullWidth
            value={newDevice.type}
            onChange={(e) =>
              setNewDevice({ ...newDevice, type: e.target.value })
            }
            size={isMobile ? "small" : "medium"}
          />
          <TextField
            margin="dense"
            label="设备密码"
            type="password"
            fullWidth
            value={newDevice.password}
            onChange={(e) =>
              setNewDevice({ ...newDevice, password: e.target.value })
            }
            size={isMobile ? "small" : "medium"}
          />
        </DialogContent>
        <DialogActions>
          <Button onClick={() => setOpenDialog(false)}>取消</Button>
          <Button onClick={handleAddDevice} variant="contained">
            添加
          </Button>
        </DialogActions>
      </Dialog>

      <Snackbar
        open={!!error}
        autoHideDuration={6000}
        onClose={() => setError(null)}
      >
        <Alert onClose={() => setError(null)} severity="error">
          {error}
        </Alert>
      </Snackbar>
    </Box>
  );
};

export default DeviceList; 